package server;
import java.io.*;
import java.util.*;
import java.net.*;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * <p>Title: WebServer.java</p>
 *
 * <p>Description: This is the main class of the server. This is where
 * everything is instantiated and configured. Here is also where multithreading
 * of the server will occur.</p>
 *
 * <p>Copyright: Copyright (c) 2005</p>
 *
 * <p>Company: </p>
 * @author Tracie Hong and Luping May
 * @version 1.0
 */
public class WebServer {

  /**
   * Here you will create your server, configure all the settings and listen to
   * the port designated within your configuration. Whenever a request comes in,
   * you will need to process that request appropriately and respond as needed.
   *
   * @param args String[]
   */
  public static void main(String[] args) {
    try{
        ServerSocket ding = null;
        Socket dong = null;
        clientThread newClient = null;
        HttpdConf newConf = new HttpdConf();
        newConf.readHttpd("C:\\csc667\\java_webserver\\htdocs2\\conf\\httpd.667.conf");
        newConf.readMIME("C:\\csc667\\java_webserver\\conf\\mime.types");
//        newConf.testPrint();
//        System.exit(1);
        try {
            // ServerSocket, Socket are availalbe Java classes
            ding = new ServerSocket(newConf.getListen());
            System.out.println("Opened socket " + newConf.getListen());
            while (true) {
        	// keeps listening for new clients, one at a time
                try {
                        dong = ding.accept();
                        newClient = new clientThread(dong, newConf);
                        newClient.start();
                }catch(Exception e){
                    System.out.println("Error reading from socket");
                    System.exit(1);
                }
            }
        }catch(IOException e){
            System.out.println("Error reading from socket");
            System.exit(1);
        }
    }catch(Exception e){
            System.out.println("Error reading from socket");
            System.exit(1);
    }

  }
}

  /**
   * Private class used for multithreading
   */
class clientThread extends Thread {
    private Socket inComingSocket;
    private HttpdConf HttpdConfFile;

    /**
     * Constructor used to start a thread.
     *
     * @param incoming Socket value which designates the socket used by the client
     * @param hcf HttpdConf object created upon server startup.
     */
    public clientThread(Socket incoming, HttpdConf hcf) {
        inComingSocket = incoming;
        HttpdConfFile = hcf;
    }

    /**
     * Used to run your server thread. Here is where you will be processing all
     * requests and returning your responses.
     */
    @Override
    public void run() {
            try{
                InetAddress ip = inComingSocket.getInetAddress();
                BufferedReader in;
                in = new BufferedReader(new InputStreamReader(inComingSocket.getInputStream()));
                Request clientRequest = new Request();
                clientRequest.parse(in);
                clientRequest.setHttpdConf(HttpdConfFile);
                Environment environmentVariables = new Environment(HttpdConfFile, clientRequest, inComingSocket);
                Response serverResponse = new Response();
                environmentVariables.setEnv();
                serverResponse.processRequest(clientRequest, HttpdConfFile.getMIMEtable(), environmentVariables);
                serverResponse.writeOutput(inComingSocket.getOutputStream());
                System.out.println("Exe");
                serverResponse.writeToLog(HttpdConfFile.getLogFile(), ip.getHostName());
                inComingSocket.close();
            } catch (IOException ex) {
                Logger.getLogger(WebServer.class.getName()).log(Level.SEVERE, null, ex);
            }
    }
}
